package com.nnnu.wsnackshop.controller.admin;

import com.nnnu.wsnackshop.constant.MessageConstants;
import com.nnnu.wsnackshop.pojo.dto.AddProductDTO;
import com.nnnu.wsnackshop.pojo.dto.BatchUpdateStatusDTO;
import com.nnnu.wsnackshop.pojo.dto.ProductPageDTO;
import com.nnnu.wsnackshop.pojo.dto.UpdateProductDTO;
import com.nnnu.wsnackshop.pojo.vo.ProductVO;
import com.nnnu.wsnackshop.result.PageResult;
import com.nnnu.wsnackshop.result.Result;
import com.nnnu.wsnackshop.service.IProductsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@RestController("adminProductsController")
@RequestMapping("/api/admin/products")
@Tag(name = "管理端-商品接口")
@Slf4j
@Validated
@RequiredArgsConstructor
public class ProductsController {

    private final IProductsService productsService;

    @Operation(summary = "分页查询商品")
    @GetMapping("/page")
    @RequiresRoles(value = { "superAdmin", "admin" }, logical = Logical.OR)
    @RequiresPermissions("product:read")
    public Result<PageResult<ProductVO>> pageProducts(@Valid @ParameterObject ProductPageDTO dto) {
        log.info("分页查询商品：{}", dto);
        return Result.success(productsService.pageProducts(dto), MessageConstants.SELECT_OK);
    }

    @Operation(summary = "新增商品")
    @PostMapping
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:create")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular",
            "userProductPage" }, allEntries = true)
    public Result<Void> addProduct(@Valid @RequestBody @Parameter(description = "新增商品DTO") AddProductDTO dto) {
        log.info("新增商品：{}", dto);
        productsService.addProduct(dto);
        return Result.success(MessageConstants.ADD_OK);
    }

    @Operation(summary = "更新商品")
    @PutMapping
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:update")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular",
            "userProductPage" }, allEntries = true)
    public Result<Void> updateProduct(@Valid @RequestBody @Parameter(description = "更新商品DTO") UpdateProductDTO dto) {
        log.info("更新商品：{}", dto);
        productsService.updateProduct(dto);
        return Result.success(MessageConstants.OPERATION_SUCCESSFUL);
    }

    @Operation(summary = "批量删除商品")
    @DeleteMapping
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:delete")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular",
            "userProductPage" }, allEntries = true)
    public Result<Void> deleteProducts(
            @RequestParam @Parameter(description = "商品ID列表", in = ParameterIn.QUERY) List<Integer> ids) {
        log.info("批量删除商品：{}", ids);
        productsService.deleteProducts(ids);
        return Result.success(MessageConstants.OPERATION_SUCCESSFUL);
    }

    @Operation(summary = "修改商品状态")
    @PutMapping("/{id}/status/{status}")
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:update")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular",
            "userProductPage" }, allEntries = true)
    public Result<Void> updateStatus(
            @PathVariable @Parameter(description = "商品ID", in = ParameterIn.PATH) Integer id,
            @PathVariable @Parameter(description = "状态", in = ParameterIn.PATH) Integer status) {
        log.info("更新商品状态：id={}, status={}", id, status);
        productsService.updateStatus(id, status);
        return Result.success(MessageConstants.OPERATION_SUCCESSFUL);
    }

    @Operation(summary = "商品详情")
    @GetMapping("/{id}")
    @RequiresRoles(value = { "superAdmin", "admin" }, logical = Logical.OR)
    @RequiresPermissions("product:read")
    public Result<ProductVO> getProductDetail(
            @PathVariable @Parameter(description = "商品ID", in = ParameterIn.PATH) Integer id) {
        log.info("查询商品详情：{}", id);
        return Result.success(productsService.getProductDetail(id), MessageConstants.SELECT_OK);
    }

    @Operation(summary = "下载商品导入模板")
    @GetMapping("/template")
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:read")
    public void downloadTemplate(HttpServletResponse response) throws IOException {
        log.info("下载商品导入模板");
        productsService.downloadTemplate(response);
    }

    @Operation(summary = "导出商品Excel")
    @GetMapping("/export")
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:export")
    public void exportProducts(HttpServletResponse response) throws IOException {
        log.info("导出商品Excel");
        productsService.exportProducts(response);
    }

    @Operation(summary = "导入商品Excel（含图片）")
    @PostMapping("/import")
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:import")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular" }, allEntries = true)
    public Result<Void> importProducts(
            @RequestParam("file") MultipartFile file) throws IOException {
        log.info("导入商品Excel");
        productsService.importProducts(file);
        return Result.success(MessageConstants.ADD_OK);
    }

    @Operation(summary = "批量更新商品状态")
    @PutMapping("/batch/status")
    @RequiresRoles("superAdmin")
    @RequiresPermissions("product:update")
    @CacheEvict(cacheNames = { "userProductByStoreCategory", "userProductPopular" }, allEntries = true)
    public Result<Void> batchUpdateStatus(
            @RequestBody @Parameter(description = "批量更新状态DTO") BatchUpdateStatusDTO dto) {
        log.info("批量更新商品状态：{}", dto);
        productsService.batchUpdateStatus(dto);
        return Result.success(MessageConstants.OPERATION_SUCCESSFUL);
    }

    @Operation(summary = "获取商品销售数据")
    @GetMapping("/{id}/sales-data")
    @RequiresRoles(value = { "superAdmin", "admin" }, logical = Logical.OR)
    @RequiresPermissions("product:read")
    public Result<Object> getProductSalesData(
            @PathVariable @Parameter(description = "商品ID", in = ParameterIn.PATH) Integer id) {
        log.info("查询商品销售数据：{}", id);
        return Result.success(productsService.getProductSalesData(id), MessageConstants.SELECT_OK);
    }
}
